package com.example.demo.netty;

import com.google.common.base.Throwables;
import compaser.enums.Ops;
import compaser.proto.command.*;
import compaser.proto.utils.BuffCompase;
import io.netty.buffer.ByteBuf;
import io.netty.buffer.ByteBufUtil;
import io.netty.channel.ChannelHandler;
import io.netty.channel.ChannelHandlerContext;
import io.netty.channel.SimpleChannelInboundHandler;
import io.vertx.core.buffer.Buffer;
import lombok.extern.log4j.Log4j2;

import java.util.Arrays;
import java.util.List;
import java.util.Optional;

/**
 * @author panyundong
 */
@ChannelHandler.Sharable
@Log4j2
public class MattressSocketServerHandler extends SimpleChannelInboundHandler<byte[]> {

    private final BuffCompase buffCompase;

    public MattressSocketServerHandler(BuffCompase buffCompase) {
        this.buffCompase = buffCompase;
    }

    @Override
    protected void channelRead0(ChannelHandlerContext ctx, byte[] msg) throws Exception {
        Optional<List<AbstractIbisCommand>> commandOptional = buffCompase.decode(msg);
        commandOptional.ifPresent(list -> {
            list.forEach(c -> {
                c.readFull();
                Ops ops = c.getOps();
                log.info("receive IbisCommand [{}]", c);
                switch (ops) {
                    case HEARTBEAT_CMD:
                        handleHeartbeatRequest((HeartbeatCommand) c, ctx);
                        break;
                    case HEART_BREATH_CMD:
                        handleHeartBreathRequest((HeartAndBreathCommand) c, ctx);
                        break;
                    case ONE_MIN_HEART_BREATH_CMD:
                        handleOneHeartBreathRequest((OneMinHeartAndBreathCommand) c, ctx);
                        break;
                    case ONLINE_IN_CMD:
                    case ONLINE_AWAY_CMD:
                    case ONLINE_FAULT_CMD:
                        handleOnlineInCmdrequest((SyncStateCommand) c, ctx);
                        break;
                    default:
                        log.debug("no handle for [{}]", ops);
                }
            });
        });
    }

    @Override
    public void exceptionCaught(ChannelHandlerContext ctx, Throwable cause) {
        log.error("[{}] 发生异常了,{}", ctx.channel(), Throwables.getStackTraceAsString(cause));
    }

    @Override
    public void channelActive(ChannelHandlerContext ctx) throws Exception {
        log.info("有一个设备连接上来了: {} ", ctx.channel());
    }

    @Override
    public void channelInactive(ChannelHandlerContext ctx) throws Exception {
        log.error("设备连接被重置了");
    }

    @Override
    public void userEventTriggered(ChannelHandlerContext ctx, Object evt) throws Exception {
        log.warn("[{}]超时了", ctx.channel());
    }

    private void handleHeartbeatRequest(HeartbeatCommand c, ChannelHandlerContext ctx) {
        log.info("handle heartbeatCommand [{}]", c);
        Buffer buffer = HeartbeatCommand.newHeartbeatResponse();
        ByteBuf buf = ctx.alloc().buffer();
        buf.writeBytes(buffer.getBytes());
        ctx.writeAndFlush(buf);
    }

    private void handleOneHeartBreathRequest(OneMinHeartAndBreathCommand c, ChannelHandlerContext ctx) {
        log.info("handle OneMinHeartAndBreathCommand [{}]", c);
    }

    private void handleHeartBreathRequest(HeartAndBreathCommand c, ChannelHandlerContext ctx) {
        log.info("handle HeartAndBreathCommand [{}]", c);
    }

    private void handleOnlineInCmdrequest(SyncStateCommand c, ChannelHandlerContext ctx) {
        log.info("handle SyncStateCommand [{}]", c.getState());
    }
}
